#ifndef __WED_MEMHEAP_H__
#define __WED_MEMHEAP_H__
#include <stdio.h>
#include <stdint.h>

#include "Wed_common.h"
#include "Wed_errno.h"
#include "print/wed_print.h"
#include "kernel/Wed_mutex.h"

/* \brief 魔法数 */
#define WED_MEMHEAP_MAGIC         0x1ea01ea0
/* \brief 对齐大小 */
#define WED_MEMHEAP_ALIGN_SIZE    4

#define WED_MEMHEAP_ITEM_SIZE     WED_ALIGN(sizeof(struct Wed_memheap_item), WED_MEMHEAP_ALIGN_SIZE)

#define WED_MEMHEAP_ITEM_USED     0x01
#define WED_MEMHEAP_ITEM_FREED    0x00
/* \brief 内存堆最小分配内存大小 */
#define WED_MEMHEAP_MINIALLOC     12
/* \brief 获取内存条目内存大小 */
#define WED_MEMITEM_SIZE_GET(p_item)    ((unsigned long)p_item->p_next - (unsigned long)p_item - WED_MEMHEAP_ITEM_SIZE)

struct Wed_memheap;

/* \brief 内存堆条目结构体 */
struct Wed_memheap_item {
    uint32_t                 magic;         /* 魔法书 */
    struct Wed_memheap      *p_memheap;     /* 所属内存堆结构体地址 */

    struct Wed_memheap_item *p_next;        /* 下一个内存条目 */
    struct Wed_memheap_item *p_prev;        /* 上一个内存条目 */

    struct Wed_memheap_item *p_next_free;   /* 下一个空闲的内存条目 */
    struct Wed_memheap_item *p_prev_free;   /* 上一个空闲内存条目 */
};

/* \brief 内存堆结构体 */
struct Wed_memheap {
    void                    *p_start_addr;    /* 内存堆起始地址 */
    uint32_t                 mem_size;        /* 内存大小 */
    uint32_t                 available_size;  /* 可用内存大小 */
    uint32_t                 max_used_size;   /* 已使用的最大大小 */
    struct Wed_memheap_item *p_block_list;    /*  */
    struct Wed_memheap_item *p_free_list;     /* 空闲条目链表 */
    struct Wed_memheap_item  free_header;     /* 空闲条目链表头部 */
    struct Wed_mutex         lock;            /* 互斥锁 */
};



/**
 * \brief 内存堆初始化
 *
 * @param p_mem_heap   要初始化的内存堆结构体
 * @param p_start_addr 内存起始地址
 * @param size         内存大小
 *
 * @return 成功返回 0
 */
int Wed_memheap_init(struct Wed_memheap *p_mem_heap,
                     void               *p_start_addr,
                     unsigned long       size);
/**
 * \brief 内存堆内存分配
 *
 * @param p_mem_heap 内存堆结构体
 * @param size       要分配的内存大小
 *
 * @return 成功返回分配的内存地址
 */
void *Wed_memheap_malloc(struct Wed_memheap *p_mem_heap, unsigned long size);
#endif
